/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package examplesocket;

import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 *
 * @author caos
 */
public class CryptHelper {
    private PublicKey publicKey;
    private PrivateKey privateKey;
    private SecretKeySpec AESKey;
    private static final CryptHelper INSTANCE = new CryptHelper();
    private CryptHelper()
    {}    
    
    public static CryptHelper getInstance() {
        return INSTANCE;
    }
    
    public void cryptHelperInitializer()
    {
        try {
            KeyPairGenerator keyGenRSA = KeyPairGenerator.getInstance("RSA");
            keyGenRSA.initialize(1024);
            KeyPair keypair = keyGenRSA.genKeyPair();
            this.privateKey = keypair.getPrivate();
            this.publicKey = keypair.getPublic();
            
            KeyGenerator keyGenAES=KeyGenerator.getInstance("AES");
            keyGenAES.init(128);
             SecretKey skey = keyGenAES.generateKey();
             byte[] raw = skey.getEncoded();

            this.AESKey = new SecretKeySpec(raw, "AES");           
        } catch (NoSuchAlgorithmException ex) {}
    }
    
    private static String asHex(byte[] src)
    {
        StringBuffer hexStr=new StringBuffer();
        for(byte b : src)
        {
            String tmp = Integer.toHexString(0xFF & b);
            if(tmp.length()==1)
                hexStr.append('0');
            hexStr.append(tmp);
        }
        return hexStr.toString();
    }    
    static String MD5(String toHash)
    {
        try
        {
            byte digest[]=MessageDigest.getInstance("MD5").digest(toHash.getBytes("UTF-8"));
            return asHex(digest);
        }
        catch(Exception ex)
        {
            return null;
        }
    }        
    
    static String RSAEncrypt(String toEncode, PublicKey destPublicKey)
    {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, destPublicKey);
            byte[] cipherData = cipher.doFinal(toEncode.getBytes());
            return  new sun.misc.BASE64Encoder().encode(cipherData);
        }
        catch(Exception ex)
        {
            return null;
        }
        
    }    
    String RSAEncryptLocal(String toEncode)
    {
        return RSAEncrypt(toEncode, publicKey);
    }    

    String RSADecryptLocal(String encodedMessage)
    {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            System.out.println("**"+encodedMessage+"**");
            byte[] cipherData = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(encodedMessage));
            return new String(cipherData);
        }
        catch(Exception ex)
        {
            System.out.println("Err 95:CryptHelper: " + ex.getMessage());
            return null;
        }
    }    
    
    String AESEncryptLocal(String toEncode)
    {
        return AESEncrypt(toEncode, AESKey);
    }
    static String AESEncrypt(String toEncode, SecretKeySpec AESDestKey)
    {
        try {
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, AESDestKey);
            byte[] cipherData = cipher.doFinal(toEncode.getBytes());
            return new sun.misc.BASE64Encoder().encode(cipherData);
        }
        catch(Exception ex)
        {
            System.out.println(ex.getMessage());
            return null;
        }
    }
    
    static String AESDecrypt(String toDecode, SecretKeySpec AESDestKey)
    {
        try {
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, AESDestKey);
            byte[] original = cipher.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(toDecode));
            return new String(original);
        }
        catch(Exception ex)
        {
            System.out.println("Error 137CHelper: " + ex.getMessage());
            return null;
        }
    }
    
    String AESDecryptLocal(String toDecode)
    {
        return AESDecrypt(toDecode, AESKey);
    }

    PublicKey getPK()
    {
        return publicKey;
    }
   
    String getPKAsString()
    {
        return new sun.misc.BASE64Encoder().encode(new X509EncodedKeySpec(publicKey.getEncoded()).getEncoded());
    }
    
    String getAESFromObject(SecretKeySpec AESKey)
    {
        return new sun.misc.BASE64Encoder().encode(AESKey.getEncoded());
    }
    
}
